package com.example.s7;

import HslCommunication.Core.Transfer.IByteTransform;
import HslCommunication.Core.Transfer.RegularByteTransform;
import HslCommunication.Core.Transfer.ReverseBytesTransform;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.example.exception.OpcException;
import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.S7Serializer;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.github.s7connector.api.factory.S7SerializerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class s7connectorTest {

    //PLC数据转换
    private static IByteTransform byteTransform;

    public static void main(String[] args) {
//        testReadPlcRealData();
        //testReadPlcLRealData();
        //test90();
         test101();
    }

    public static S7Connector initConnect(){
        //PLC地址 二标段
        //String ipAddress = "172.18.1.101";
        //PLC地址 一标段
        String ipAddress = "172.18.1.90";
        //默认端口
        //int port = 102;
        int rack=0;
        int slot=3;
        int timeout=10000;
        S7Connector s7connector=
                S7ConnectorFactory
                        .buildTCPConnector()
                        .withHost(ipAddress)
                        //.withPort(port) //optional
                        //.withRack(rack) //optional
                        //.withSlot(slot) //optional
                        .withTimeout(timeout) //连接超时时间
                        .build();
        S7Serializer s7Serializer2L = S7SerializerFactory.buildSerializer(s7connector);
        return s7connector;

    }

    /**
     * 测试90
     */
    public static void test90() {
        SiemensS7Net siemensTcpNet = new SiemensS7Net(SiemensPLCS.S1500, "172.18.1.90");
        // 有符号的16位 地址：DB5.DBW528   字段名称：new_silo2_high_voltage_in
        //byte[] getBytes = siemensTcpNet.Read(DaveArea.DB, 5, 2, 528);
        //OperateResultExOne<byte[]> read = siemensTcpNet.Read("DB572.48", (short) 4);
        OperateResultExOne<byte[]> read = siemensTcpNet.Read("DB5.DBW524", (short) 2);
        //String str = getBinaryStrFromByte(getBytes[0]);
        //System.out.println("getDoubleData:"+str);
        //105代表读取的长度
        //OperateResultExOne<byte[]> read = siemensTcpNet.Read("I32", (short) 1);
        OperateResultExOne<boolean[]> read1 = siemensTcpNet.ReadBool("I188", (short) 1);
        OperateResultExOne<Boolean> i188 = siemensTcpNet.ReadBool("I188.4");
        OperateResultExOne<Boolean> i1881 = siemensTcpNet.ReadBool("I188.5");
        OperateResultExOne<Boolean> i1882 = siemensTcpNet.ReadBool("I188.6");

        if (read.IsSuccess) {
            // I74: 10100101
            // 2:1 4:0 0:1 3:0
            // I188: 11000100
            // 4:0 5:0 3:0 2:1 7:1 6:1
            byte[] content = read.Content;
            String str = getBinaryStrFromByte(content[0]);
            System.out.println("getDoubleData:"+str);
            //2是下标
            //short no = siemensTcpNet.getByteTransform().TransInt16(content, 2);
            //System.out.println(no);
        }

    }

    /**
     * 测试101
     */
    public static void test101() {
        SiemensS7Net siemensTcpNet = new SiemensS7Net(SiemensPLCS.S400, "172.18.1.101");
        // 有符号的16位 地址：DB5.DBW528   字段名称：new_silo2_high_voltage_in
        //byte[] getBytes = siemensTcpNet.Read(DaveArea.DB, 5, 2, 528);
        //OperateResultExOne<byte[]> read = siemensTcpNet.Read("DB572.48", (short) 4);
        OperateResultExOne<byte[]> read = siemensTcpNet.Read("DB554.48", (short) 4);
        if (read.IsSuccess) {
            // I74: 10100101
            // 2:1 4:0 0:1 3:0
            // I188: 11000100
            // 4:0 5:0 3:0 2:1 7:1 6:1
            byte[] content = read.Content;
            String str = getBinaryStrFromByte(content[0]);
            System.out.println("getDoubleData:"+str);
            //2是下标
            //short no = siemensTcpNet.getByteTransform().TransInt16(content, 2);
            //System.out.println(no);
        }

        //OperateResultExOne<double[]> double1 = siemensTcpNet.ReadDouble("DB4.2", (short) 4);
        //String str = getBinaryStrFromByte(getBytes[0]);
        //System.out.println("getDoubleData:"+str);
        //105代表读取的长度
        //OperateResultExOne<byte[]> read = siemensTcpNet.Read("I32", (short) 1);
        OperateResultExOne<boolean[]> read1 = siemensTcpNet.ReadBool("I188", (short) 1);
        IByteTransform iByteTransform = new ReverseBytesTransform();
        //byte[] valueBytes = Arrays.copyOfRange(bytes, count, count + block.getLength());
        //float value = iByteTransform.TransSingle(read.Content, 0);
        float value = iByteTransform.TransSingle(read.Content, 0);
        System.out.println("value: " + value);
        OperateResultExOne<Boolean> i188 = siemensTcpNet.ReadBool("I188.4");
        OperateResultExOne<Boolean> i1881 = siemensTcpNet.ReadBool("I188.5");
        OperateResultExOne<Boolean> i1882 = siemensTcpNet.ReadBool("I188.6");

        /*if (read.IsSuccess) {
            // I74: 10100101
            // 2:1 4:0 0:1 3:0
            // I188: 11000100
            // 4:0 5:0 3:0 2:1 7:1 6:1
            byte[] content = read.Content;
            String str = getBinaryStrFromByte(content[0]);
            System.out.println("getDoubleData:"+str);
            //2是下标
            //short no = siemensTcpNet.getByteTransform().TransInt16(content, 2);
            //System.out.println(no);
        }*/

    }

    /**
     * 读取DIO类型的PLC数据
     */
    public static void test() {
        SiemensS7Net siemensTcpNet = new SiemensS7Net(SiemensPLCS.S400, "172.18.1.101");


        //105代表读取的长度
        OperateResultExOne<byte[]> read = siemensTcpNet.Read("I32", (short) 1);
        OperateResultExOne<boolean[]> read1 = siemensTcpNet.ReadBool("I188", (short) 1);
        OperateResultExOne<Boolean> i188 = siemensTcpNet.ReadBool("I188.4");
        OperateResultExOne<Boolean> i1881 = siemensTcpNet.ReadBool("I188.5");
        OperateResultExOne<Boolean> i1882 = siemensTcpNet.ReadBool("I188.6");

        if (read.IsSuccess) {
            // I74: 10100101
            // 2:1 4:0 0:1 3:0
            // I188: 11000100
            // 4:0 5:0 3:0 2:1 7:1 6:1
            byte[] content = read.Content;
            String str = getBinaryStrFromByte(content[0]);
            System.out.println("getDoubleData:"+str);
            //2是下标
            //short no = siemensTcpNet.getByteTransform().TransInt16(content, 2);
            //System.out.println(no);
        }
    }

    /**
     * 读取PLC中的浮点型float(real 4字节)数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public static void testReadPlcRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数：DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数：DB块地址，若plc中是DB1000，则填1000
        //第三个参数：数据长度
        //第四个参数：偏移量
        //byte [] bytes = ByteBuffer.allocate(8).putDouble(1729.1729).array();
        //byte [] bytes = { 64, -101, 4, -79, 12, -78, -107, -22 };
        //System.out.println();

        byte[] getBytes = s7Connector.read(DaveArea.DB, 4, 4, 64);
        //byte[] getBytes = s7Connector.read(DaveArea.DB, 4, 4, 104);
        Float getValue = ByteBuffer.wrap(getBytes).getFloat();
        System.out.println("getFloatData:"+getValue);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 读取PLC中的浮点型Double(8字节)数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public static void testReadPlcLRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数：DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数：DB块地址，若plc中是DB1000，则填1000
        //第三个参数：数据长度
        //第四个参数：偏移量
        //byte [] bytes = ByteBuffer.allocate(8).putDouble(1729.1729).array();
        //byte [] bytes = { 64, -101, 4, -79, 12, -78, -107, -22 };
        //System.out.println();

        //byte[] getBytes = s7Connector.read(DaveArea.DB, 47, 8, 2);
        // -120 -> 10001000
        // DB47,D140.0
        //byte[] getBytes = s7Connector.read(DaveArea.DB, 47, 1, 140);
        // 有符号的16位 地址：DB5.DBW528   字段名称：new_silo2_high_voltage_in
        byte[] getBytes = s7Connector.read(DaveArea.DB, 5, 2, 528);
        String str = getBinaryStrFromByte(getBytes[0]);
        System.out.println("getDoubleData:"+str);
        //char a = ByteBuffer.wrap(getBytes).getChar();
        //Double getValue = ByteBuffer.wrap(getBytes).getDouble();
        //System.out.println("getDoubleData:"+getValue);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 把byte转化成2进制字符串
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte(byte b) {
        String result = "";
        byte a = b;
        ;
        for (int i = 0; i < 8; i++) {
            byte c = a;
            a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
            a = (byte) (a << 1);
            if (a == c) {
                result = "0" + result;
            } else {
                result = "1" + result;
            }
            a = (byte) (a >> 1);
        }
        return result;
    }


}
